import React from "react"
import { connect } from "react-redux"
import $ from "jquery"
import {
	getUrlIcon,
	getArraySortedByProp,
	getDataFromLocalStorage,
	getObjExchangeByExchangeId,
} from "../common"
import {
	IAppProps,
	ILoginUser,
	ICreateNewUser,
	IUpdateUser,
	IGetP2POrders,
	IGetMerchantOrders,
	IGetMerchantAdvs,
	IGetMerchantDetails,
	IGetBalances,
	ITransferAsset,
	IGetEditableAdv,
	IGetEditableOrder,
	IChangeAdvStatus,
	IUpdateAdv,
	IUpdateItemDetails,
	IGetHistorySpotOrders,
	IGetActiveSpotOrders,
	IInsertOrderToDB,
	IInsertBalanceToDB,
	IInsertNewItemToDB,
	ICheckOrderStatus,
	IGetReportOrders,
	IGetGroupItems,
	IGetDataTickers,
	IGetFundingRates,
	IGetSpreads,
	ISaveSpreads,
} from "../types"
import {
	getP2POrdersAction,
	getMerchantOrdersAction,
	getMerchantAdvsAction,
	getMerchantDetailsAction,
	getBalancesAction,
	transferAssetAction,
	getReportOrdersAction,
	getEditableAdvAction,
	getEditableOrderAction,
	updateAdvAction,
	updateItemDetailsAction,
	changeAdvStatusAction,
	handlerFilterDetailsAction,
	handlerAdvDetailsAction,
	handlerUserProfileAction,
	handlerPopupWindowAction,
	logoutUserAction,
	loginUserAction,
	createNewUserAction,
	updateUserAction,
	resetPasswordAction,
	getHistorySpotOrdersAction,
	getActiveSpotOrdersAction,
	insertOrderToDBAction,
	insertBalanceToDBAction,
	insertNewItemToDBAction,
	checkOrderStatusesAction,
	getGroupItemsAction,
	getDataTickersAction,
	getFundingRatesAction,
	getSpreadsAction,
	saveSpreadsAction,
} from "../actions"
import {
	ExchangeSwitcher,
	CounterPanel,
	ModalMessages,
	CreateUserModal,
	AddNewExchangeModal,
	AddNewCurrencyModal,
	AddNewPayMethodModal,
	AddNewSubAccountModal,
	PasswordResetModal,
	EditProfileUserModal,
	EditPassUserModal,
	EditOrderModal,
	EditPaymentItemModal,
	EditExchangeItemModal,
	EditOrderStatusModal,
	EditCurrencyItemModal,
	EditUserPayTypesModal,
	BalanceInsertModal,
} from "../components"
import { TradeModul } from "./TradeModul"
import {
	CONSTANTS,
	USER_DATA_STORAGE,
	CONSTANTS_STORAGE,
	REPORTS_STORAGE,
} from "../constants"

import "bootswatch/dist/superhero/bootstrap.min.css"
import "bootstrap/dist/js/bootstrap.min.js"
import "../styles/App.sass"

const App: React.FC<IAppProps> = props => {
	const {
		store,
		getP2POrdersToApp,
		getMerchantOrdersToApp,
		getMerchantAdvsToApp,
		getMerchantDetailsToApp,
		getHistorySpotOrdersToApp,
		getActiveSpotOrdersToApp,
		insertOrderToDBToApp,
		insertBalanceToDBToApp,
		insertNewItemToDBToApp,
		checkOrderStatusesToApp,
		getReportOrdersToApp,
		getDataTickersToApp,
		getFundingRatesToApp,
		getSpreadsToApp,
		saveSpreadsToApp,
		getBalancesToApp,
		getEditableAdvToApp,
		getEditableOrderToApp,
		updateAdvToApp,
		updateItemDetailsToApp,
		transferAssetToApp,
		changeAdvStatusToApp,
		handlerFilterDetailsToApp,
		handlerAdvDetailsToApp,
		handlerUserProfileToApp,
		handlerPopupWindowToApp,
		logoutUserToApp,
		loginUserToApp,
		createNewUserToApp,
		updateUserToApp,
		resetPasswordToApp,
		getGroupItemsToApp,
	} = props

	const {
		loading,
		messagePopup,
		filterDetails,
		userProfile,
		userOrderStatuses,
		currentCourses,
		fundingRates,
		spreads,
		reports,
	} = store

	// получаем константы Exchanges, PayTypes, Currencies из lS
	const DATA_CONSTANTS = getDataFromLocalStorage(CONSTANTS_STORAGE)
	const dataConstants = {
		exchanges:
			DATA_CONSTANTS === null
				? CONSTANTS.ARRAY_EXCHANGES
				: DATA_CONSTANTS.exchanges,
		currencies: DATA_CONSTANTS === null ? [] : DATA_CONSTANTS.currencies,
		paytypes:
			DATA_CONSTANTS === null
				? []
				: getArraySortedByProp("payType", DATA_CONSTANTS.payTypes),
		tickers:
			DATA_CONSTANTS === null ? currentCourses : DATA_CONSTANTS.tickers,
		statuses: DATA_CONSTANTS === null ? [] : DATA_CONSTANTS.statuses,
	}

	// получаем данные о report'e из localStorage
	const reportStorage = getDataFromLocalStorage(REPORTS_STORAGE)
	if (reportStorage !== null) {
		reports.reportCost = reportStorage.reportCost
		reports.reportStats = reportStorage.reportStats
		reports.reportBalances = reportStorage.reportBalances
		reports.reportSpotOrders = reportStorage.reportSpotOrders
		reports.reportMerchantOrders = reportStorage.reportMerchantOrders
	}

	// получаем данные о user'e из localStorage
	const userLocalStorage = getDataFromLocalStorage(USER_DATA_STORAGE)

	// Если данные о user'e есть в localStorage
	if (userLocalStorage !== null) {
		userProfile.auth = userLocalStorage.auth
		userProfile.token = userLocalStorage.token
		userProfile.id = userLocalStorage.id
		userProfile.login = userLocalStorage.login
		userProfile.lang = userLocalStorage.lang
		userProfile.theme = userLocalStorage.theme
		userProfile.status = userLocalStorage.status
		userProfile.advSell = userLocalStorage.advSell
		userProfile.subAccounts = userLocalStorage.subAccounts
		userProfile.userProperties = userLocalStorage.userProperties
	}

	// Параметры для Scrollbar
	const widthDisplay = document.documentElement.clientWidth
	const heightDisplay = document.documentElement.clientHeight
	const scrollStyle = {
		height: heightDisplay - 200,
		width: widthDisplay,
	}

	const [exchangeActive, handlerSwitcher] = React.useState(
		"63039ac2956b2f07f0e56f12"
	)

	// Получение иконок доступных оплат
	const getPayDots = (exchange: string, arr: any) => {
		const listDots = arr.map((item: any, index: number) => {
			let icon = ""
			// BN PX HB KX BZ GX BT
			if (
				exchange === "BN" ||
				exchange === "PX" ||
				exchange === "HB" ||
				exchange === "KX" ||
				exchange === "BZ" ||
				exchange === "GX" ||
				exchange === "BT" ||
				exchange === "BP" ||
				exchange === "MG" ||
				exchange === "GT" ||
				exchange === "BG" ||
				exchange === "CX" ||
				exchange === "BX" ||
				exchange === "TW" ||
				exchange === "XG" ||
				exchange === "CN" ||
				exchange === "BM"
			)
				icon = item
			else if (exchange === "All") icon = item.payName

			return (
				<span className="icon-pay-dots" key={index}>
					<img alt="-" src={getUrlIcon("Payment", icon)} title={icon} />
				</span>
			)
		})

		return listDots
	}

	// Получение списка options для select
	const getListOption = (arr: any, nameList: string, exchange?: string) => {
		const list = arr.map((item: any, index: number) => {
			let elemItemValue
			let elemItemName
			// Исключение для статусов merchant-ордеров
			if (nameList === "payTypeList") {
				elemItemValue = item.payType
				elemItemName = item.payType
			} else if (nameList === "listFiatOptions") {
				elemItemValue = item.fiat
				elemItemName = item.fiat
			} else if (
				nameList === "OrderAssetType" ||
				nameList === "OrderSideType" ||
				nameList === "advStatusActive"
			) {
				elemItemValue = item.value
				elemItemName = item.status
			} else if (nameList === "OrderStatusType") {
				elemItemName = item.status
				if (exchange === "Binance") {
					elemItemValue = item.value
				} else if (exchange === "Bybit") {
					elemItemValue = item.valueBT
				} else if (exchange === "Pexpay") {
					elemItemValue = item.valuePX
				} else if (exchange === "Huobi") {
					elemItemValue = item.valueHB
				} else if (exchange === "Okex") {
					elemItemValue = item.valueKX
				}
			} else if (
				nameList === "quantityPages" ||
				nameList === "userPayTypeList"
			) {
				elemItemValue = item
				elemItemName = item
			} else if (nameList === "listExchanges") {
				elemItemValue = item.name
				elemItemName = item.name
			} else if (nameList === "reportExchanges") {
				elemItemValue = item.shortName
				elemItemName = item.name
			}
			return (
				<option key={index} value={elemItemValue}>
					{elemItemName}
				</option>
			)
		})
		return list
	}

	// валидатор всей формы
	const validateForm = (obj: any, idForm: string) => {
		// счётчик количества НЕкорректно заполненных полей
		let invalidCount = 0

		for (const key in obj) {
			if (obj[key] === null || obj[key] === "") {
				$("#" + key)
					.removeClass("is-valid")
					.addClass("is-invalid")
				invalidCount += 1
			} else
				$("#" + key)
					.removeClass("is-invalid")
					.addClass("is-valid")
		}

		if (invalidCount === 0) {
			// для формы addUser
			if (idForm === "addUser") {
				createNewUserToApp(obj)
				$("#modal-addUser").modal("hide")
			}
			// для формы editPassUser
			else if (idForm === "editPassUser") {
				updateUserToApp(obj)
				$("#modal-editPassUser").modal("hide")
			}
			// для формы editProfileUser
			else if (idForm === "editProfileUser") {
				// console.log(obj)
				updateUserToApp(obj)
				$("#modal-editProfileUser").modal("hide")
			}
			// для формы resetPass
			else if (idForm === "resetPass") {
				resetPasswordToApp(obj)
				$("#modal-reset").modal("hide")
			}

			// clear feilds and remove classes is-valid is-invalid
			// tslint:disable-next-line: forin
			for (const key in obj) {
				$("#" + key)
					.removeClass("is-valid is-invalid")
					.val("")
			}
		}
	}

	return (
		<div className="container App">
			<TradeModul
				objExchange={getObjExchangeByExchangeId(filterDetails.activeExchange)}
				userProfile={userProfile}
				filterDetails={filterDetails}
				userOrderStatuses={userOrderStatuses}
				reportCost={reports.reportCost}
				reportStats={reports.reportStats}
				reportBalances={reports.reportBalances}
				reportMerchantOrders={reports.reportMerchantOrders}
				reportSpotOrders={reports.reportSpotOrders}
				getHistorySpotOrders={getHistorySpotOrdersToApp}
				getActiveSpotOrders={getActiveSpotOrdersToApp}
				loading={loading}
				currentCourses={dataConstants.tickers}
				fundingRates={fundingRates}
				spreads={spreads}
				scrollStyle={scrollStyle}
				dataConstants={dataConstants}
				getPayDots={getPayDots}
				getListOption={getListOption}
				logoutUser={logoutUserToApp}
				updateUser={updateUserToApp}
				loginUser={loginUserToApp}
				getP2POrders={getP2POrdersToApp}
				getMerchantOrders={getMerchantOrdersToApp}
				getMerchantDetails={getMerchantDetailsToApp}
				getMerchantAdvs={getMerchantAdvsToApp}
				changeAdvStatus={changeAdvStatusToApp}
				insertOrderToDB={insertOrderToDBToApp}
				insertNewItemToDB={insertNewItemToDBToApp}
				checkOrderStatuses={checkOrderStatusesToApp}
				getBalances={getBalancesToApp}
				transferAsset={transferAssetToApp}
				getReportOrders={getReportOrdersToApp}
				getGroupItems={getGroupItemsToApp}
				getDataTickers={getDataTickersToApp}
				getFundingRates={getFundingRatesToApp}
				getSpreads={getSpreadsToApp}
				saveSpreads={saveSpreadsToApp}
				getEditableAdv={getEditableAdvToApp}
				getEditableOrder={getEditableOrderToApp}
				updateAdv={updateAdvToApp}
				updateItemDetails={updateItemDetailsToApp}
				handlerAdvDetails={handlerAdvDetailsToApp}
				handlerFilterDetails={handlerFilterDetailsToApp}
				handlerPopupWindow={handlerPopupWindowToApp}
				handlerUserProfile={handlerUserProfileToApp}
			/>
			{userProfile.auth ? (
				<>
					<ExchangeSwitcher
						activeExchange={filterDetails.activeExchange}
						// activeExchange={exchangeActive}
						handlerSwitcher={handlerSwitcher}
						handlerFilterDetails={handlerFilterDetailsToApp}
					/>
					<CounterPanel
						userProfile={userProfile}
						loading={loading}
						exchanges={dataConstants.exchanges}
					/>
				</>
			) : null}
			<ModalMessages
				category={messagePopup.category}
				message={messagePopup.message}
			/>
			<CreateUserModal
				validateForm={validateForm}
				handlerPopupWindow={handlerPopupWindowToApp}
			/>
			<AddNewExchangeModal
				userId={userProfile.id}
				insertNewItemToDB={insertNewItemToDBToApp}
				handlerPopupWindow={handlerPopupWindowToApp}
			/>
			<AddNewCurrencyModal
				userId={userProfile.id}
				insertNewItemToDB={insertNewItemToDBToApp}
				handlerPopupWindow={handlerPopupWindowToApp}
			/>
			<AddNewPayMethodModal
				userId={userProfile.id}
				insertNewItemToDB={insertNewItemToDBToApp}
				handlerPopupWindow={handlerPopupWindowToApp}
			/>
			<AddNewSubAccountModal
				userId={userProfile.id}
				insertNewItemToDB={insertNewItemToDBToApp}
				handlerPopupWindow={handlerPopupWindowToApp}
			/>
			<PasswordResetModal
				validateForm={validateForm}
				handlerPopupWindow={handlerPopupWindowToApp}
			/>
			<EditProfileUserModal
				handlerUserProfile={handlerUserProfileToApp}
				getListOption={getListOption}
				validateForm={validateForm}
				updateUser={updateUserToApp}
				userProfile={userProfile}
				dataConstants={dataConstants}
			/>
			<EditUserPayTypesModal
				getListOption={getListOption}
				updateUser={updateUserToApp}
				userProfile={userProfile}
				dataConstants={dataConstants}
			/>
			<EditPassUserModal
				validateForm={validateForm}
				userProfile={userProfile}
			/>
			<EditOrderModal
				dataConstants={dataConstants}
				orderDetails={filterDetails.orderDetails}
				handlerFilterDetails={handlerFilterDetailsToApp}
				updateItemDetails={updateItemDetailsToApp}
			/>
			<EditPaymentItemModal
				dataConstants={dataConstants}
				itemDetails={filterDetails.itemDetails}
				handlerFilterDetails={handlerFilterDetailsToApp}
				updateItemDetails={updateItemDetailsToApp}
			/>
			<EditExchangeItemModal
				itemDetails={filterDetails.itemDetails}
				handlerFilterDetails={handlerFilterDetailsToApp}
				updateItemDetails={updateItemDetailsToApp}
			/>
			<EditOrderStatusModal
				dataConstants={dataConstants}
				itemDetails={filterDetails.itemDetails}
				handlerFilterDetails={handlerFilterDetailsToApp}
				updateItemDetails={updateItemDetailsToApp}
			/>
			<EditCurrencyItemModal
				dataConstants={dataConstants}
				itemDetails={filterDetails.itemDetails}
				handlerFilterDetails={handlerFilterDetailsToApp}
				updateItemDetails={updateItemDetailsToApp}
			/>
			<BalanceInsertModal
				userId={userProfile.id}
				admin={userProfile.status === "admin" ? true : false}
				currentCourses={dataConstants.tickers}
				balanceDetails={filterDetails.balanceDetails}
				insertBalanceToDB={insertBalanceToDBToApp}
			/>
		</div>
	)
}

const mapStateToProps = (state: any) => {
	return { store: state }
}

const mapDispatchToProps = (dispatch: any) => {
	return {
		getP2POrdersToApp: (objOrder: IGetP2POrders) =>
			dispatch(getP2POrdersAction(objOrder)),
		getMerchantOrdersToApp: (objOrder: IGetMerchantOrders) =>
			dispatch(getMerchantOrdersAction(objOrder)),
		getHistorySpotOrdersToApp: (objParams: IGetHistorySpotOrders) =>
			dispatch(getHistorySpotOrdersAction(objParams)),
		getActiveSpotOrdersToApp: (objParams: IGetActiveSpotOrders) =>
			dispatch(getActiveSpotOrdersAction(objParams)),
		insertOrderToDBToApp: (objInsertDB: IInsertOrderToDB) =>
			dispatch(insertOrderToDBAction(objInsertDB)),
		insertBalanceToDBToApp: (objBalanceDB: IInsertBalanceToDB) =>
			dispatch(insertBalanceToDBAction(objBalanceDB)),
		insertNewItemToDBToApp: (objItem: IInsertNewItemToDB) =>
			dispatch(insertNewItemToDBAction(objItem)),
		checkOrderStatusesToApp: (objCheckStatus: ICheckOrderStatus) =>
			dispatch(checkOrderStatusesAction(objCheckStatus)),
		getMerchantAdvsToApp: (objAdvs: IGetMerchantAdvs) =>
			dispatch(getMerchantAdvsAction(objAdvs)),
		getMerchantDetailsToApp: (objMerchant: IGetMerchantDetails) =>
			dispatch(getMerchantDetailsAction(objMerchant)),
		getBalancesToApp: (objOrder: IGetBalances) =>
			dispatch(getBalancesAction(objOrder)),
		getReportOrdersToApp: (objParamReport: IGetReportOrders) =>
			dispatch(getReportOrdersAction(objParamReport)),
		getGroupItemsToApp: (objParams: IGetGroupItems) =>
			dispatch(getGroupItemsAction(objParams)),
		getDataTickersToApp: (objParams: IGetDataTickers) =>
			dispatch(getDataTickersAction(objParams)),
		getFundingRatesToApp: (objParams: IGetFundingRates) =>
			dispatch(getFundingRatesAction(objParams)),
		getSpreadsToApp: (objParams: IGetSpreads) =>
			dispatch(getSpreadsAction(objParams)),
		saveSpreadsToApp: (objParams: ISaveSpreads) =>
			dispatch(saveSpreadsAction(objParams)),
		getEditableAdvToApp: (objParams: IGetEditableAdv) =>
			dispatch(getEditableAdvAction(objParams)),
		getEditableOrderToApp: (objOrder: IGetEditableOrder) =>
			dispatch(getEditableOrderAction(objOrder)),
		updateAdvToApp: (objParams: IUpdateAdv) =>
			dispatch(updateAdvAction(objParams)),
		updateItemDetailsToApp: (objItem: IUpdateItemDetails) =>
			dispatch(updateItemDetailsAction(objItem)),
		changeAdvStatusToApp: (objAdv: IChangeAdvStatus) =>
			dispatch(changeAdvStatusAction(objAdv)),
		handlerFilterDetailsToApp: (
			exchange: string,
			name: string,
			value: string | boolean
		) => dispatch(handlerFilterDetailsAction(exchange, name, value)),
		handlerAdvDetailsToApp: (name: string, value: string) =>
			dispatch(handlerAdvDetailsAction(name, value)),
		handlerUserProfileToApp: (
			exchange: string,
			name: string,
			value: string | boolean
		) => dispatch(handlerUserProfileAction(exchange, name, value)),
		handlerPopupWindowToApp: (name: string, value: string) =>
			dispatch(handlerPopupWindowAction(name, value)),
		logoutUserToApp: (token: string) => dispatch(logoutUserAction(token)),
		loginUserToApp: (objUser: ILoginUser) =>
			dispatch(loginUserAction(objUser)),
		createNewUserToApp: (objNewUser: ICreateNewUser) =>
			dispatch(createNewUserAction(objNewUser)),
		updateUserToApp: (objUser: IUpdateUser) =>
			dispatch(updateUserAction(objUser)),
		resetPasswordToApp: (userLogin: any) =>
			dispatch(resetPasswordAction(userLogin)),
		transferAssetToApp: (objParams: ITransferAsset) =>
			dispatch(transferAssetAction(objParams)),
	}
}

export default connect(mapStateToProps, mapDispatchToProps)(App)
